﻿using Anley.DomainDrivenDesign.Contract.Application;
using Anley.DomainDrivenDesign.Contract.Authorization;

namespace Anley.DomainDrivenDesign.Contract.Extension;

/// <summary>
/// 类型扩展类
/// </summary>
public static class TypeExtension
{
    /// <summary>
    /// 创建接口实例
    /// </summary>
    /// <param name="interfaceType"></param>
    public static object CreateInterfaceInstance(
        this Type interfaceType)
    {
        var instanceType = GetInstanceType(interfaceType, true);
        var instance = Activator.CreateInstance(instanceType);
        if (instance == null)
            throw new FriendlyException($"创建{instanceType.Name}的实例失败！");
        return instance;
    }

    /// <summary>
    /// 创建接口实例
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public static T CreateInterfaceInstance<T>()
    {
        return (T)CreateInterfaceInstance(typeof(T));
    }

    /// <summary>
    /// 获取实例类型
    /// </summary>
    /// <param name="baseType">接口、基类类型</param>
    /// <param name="isSingle">是否单继承</param>
    internal static Type GetInstanceType(
        this Type baseType,
        bool isSingle = false)
    {
        var subTypes = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(bt => bt.GetTypes().Where(st => st.IsClass && st.IsAssignableTo(baseType) && !st.IsInterface && !st.IsAbstract))
            .ToList();
        if (subTypes.Count == 0)
            throw new FriendlyException($"未找到{nameof(ICurrentUser)}的实现类！");
        if (isSingle)
        {
            if (subTypes.Count > 1)
                throw new FriendlyException($"{nameof(ICurrentUser)}不能存在多个实现类！");
            return subTypes.Single();
        }
        else
            return subTypes.First();
    }
}